package com.bosssoft.boss_exam_core.common.config.security;


import com.bosssoft.boss_exam_core.util.web.RequestContextUtil;
import com.bosssoft.boss_exam_db.entity.Applicant;
import io.jsonwebtoken.Claims;
import io.jsonwebtoken.Jwts;
import io.jsonwebtoken.SignatureAlgorithm;
import org.springframework.util.StringUtils;

import javax.servlet.http.HttpServletRequest;
import java.util.Date;
import java.util.Optional;

/**
 * jwt token
 * @since 2017/6/28
 */
public class ApplicantJwtTokenHelper {

    /**
     * token过期时间
     */
    public static final long VALIDITY_TIME_MS = 24 * 60 * 60 * 1000; // 24 hours  validity
    //        设置过期时间为1天

    /**
     * header中标识
     */
    public static final String AUTH_HEADER_NAME = "phone-authorization";

    /**
     * 签名密钥
     */
//  jwt token签名密钥
    private static final String SECRET = "bosssoft";


    /**
     * @param applicant
     * @return
     */
    public String create(Applicant applicant) {

        return Jwts.builder()
                .setExpiration(new Date(System.currentTimeMillis() + VALIDITY_TIME_MS))
                .claim("id", applicant.getId())
                .claim("username", applicant.getUsername())
                .claim("avatar", applicant.getAvatar())
                .signWith(SignatureAlgorithm.HS256, SECRET)
                .compact();
    }

    /**
     * 获取token的过期时间
     * @return
     */
    public Date getExpiration(String token){
        Claims claims = Jwts.parser()
                .setSigningKey(SECRET)
                .parseClaimsJws(token)
                .getBody();
        Date expirationDate = claims.getExpiration();
        return expirationDate;
    }

    /**
     * 验签
     */
    public Optional<Applicant> verifyToken(HttpServletRequest request) {
        final String token = request.getHeader(AUTH_HEADER_NAME);
        if (!StringUtils.isEmpty(token)) {
            final Applicant applicant = parse(token.trim());
            // 校验token时间是否过期
            Date expirationDate = getExpiration(token.trim());
            Date currentDate = new Date();
            //过期
            if (expirationDate.getTime()<currentDate.getTime()){
                return Optional.empty();
            }else {
                //判断该token是否有效
                if (applicant != null) {
                    //返回身份验证（通过）
                    return Optional.of(applicant);
                }
            }
        }
        return Optional.empty();
    }


    /**
     * 从token中取出管理员信息
     */
    public Applicant parse(String token) {
        Claims claims = Jwts.parser()
                .setSigningKey(SECRET)
                .parseClaimsJws(token)
                .getBody();
        Applicant applicant = new Applicant();
        applicant.setId(claims.get("id", String.class));
        applicant.setUsername(claims.get("username", String.class));
        applicant.setAvatar(claims.get("avatar", String.class));
        return applicant;
    }

    /**
     * 验签
     */
    public Optional<Applicant> getCurrentLoginUser() {
        HttpServletRequest request = RequestContextUtil.getRequest();
        Optional<Applicant> applicantOptional = verifyToken(request);
        return applicantOptional;
    }
}
